package org.raymond.iworks.study.basic.thread.cyclicbarrier;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.function.Consumer;

/**
 * @author raymond
 * @version V1.0
 * @Description: TODO
 */
@Slf4j
public class Demo2 {
    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
        test1();
    }

    public static void test1() throws BrokenBarrierException, InterruptedException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 2,
                0, TimeUnit.SECONDS, new LinkedBlockingQueue(), (r)->{
            Thread t = new Thread(r);
            return t;
        });
        CyclicBarrier barrier = new CyclicBarrier(3);
        Consumer<Boolean> c = (ex)->{
            try {
                Thread.sleep(1000);
                if(ex){
                    throw new RuntimeException("throw ex");
                }
            } catch (InterruptedException | RuntimeException e) {
                log.error("{}", e.getMessage());
            }
        };
        pool.execute(newRunnable(c, false, barrier));
        pool.execute(newRunnable(c, true, barrier));
        log.info("{} await", Thread.currentThread().getName());
        barrier.await();
        log.info("{} await end", Thread.currentThread().getName());
    }

    public static Runnable newRunnable(Consumer<Boolean> apply, boolean arg, CyclicBarrier barrier){
        return ()->{
            apply.accept(arg);
            try {
                log.info("{} await", Thread.currentThread().getName());
                barrier.await();
                log.info("{} await end", Thread.currentThread().getName());
            } catch (InterruptedException | BrokenBarrierException e) {
            }
        };
    }
}
